package core;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import domain.*;
import domain.Class;

public class ScheduleOrganizer {
	
	private static ScheduleOrganizer selfInstance = null;
	
	private ScheduleOrganizer() {
	}
	
	public static ScheduleOrganizer getInstance() {
		if (selfInstance == null) {
			selfInstance = new ScheduleOrganizer();
		}
		return selfInstance;
	}
	
	public void allocateClasses(Grid grid, final List<Class> classes, final List<Classroom> classrooms) {
		Map<PTime, Map<Turn, Schedule[]>> allocationMatrix = generateAllocationMatrix(grid);
		// TODO
		
	}
	
	private List<Schedule> listSchedulesByTurn(List<Schedule> schedules, Turn turn) {
		List<Schedule> filteredSchedules = new ArrayList<Schedule>();
		Iterator<Schedule> it = schedules.iterator();
		while (it.hasNext()) {
			Schedule s = it.next();
			if (s.getTurn().equals(turn)) {
				filteredSchedules.add(s);
			}
		}
		return filteredSchedules;
	}

	private Map<PTime, Map<Turn, Schedule[]>> generateAllocationMatrix(Grid grid) {
		Map<PTime, Map<Turn, Schedule[]>> allocationMatrix = new HashMap<PTime, Map<Turn, Schedule[]>>();
		List<PTime> schedulesDuration = grid.getExistentSchedulesDurations();
		Iterator<PTime> itPTime = schedulesDuration.iterator();
		while (itPTime.hasNext()) {
			PTime duration = itPTime.next();
			allocationMatrix.put(duration, new HashMap<Turn, Schedule[]>());
			
			List<Schedule> schedulesByDuration = grid.getSchedulesByDuration(duration);
			List<Turn> schedulesTurns = this.getExistentSchedulesTurns(schedulesByDuration);
			Iterator<Turn> itTurn = schedulesTurns.iterator();
			while (itTurn.hasNext()) {
				Turn turn = itTurn.next();
				List<Schedule> schedulesByDurationAndTurn = this.listSchedulesByTurn(schedulesByDuration, turn);
				Schedule[] sortedSchedules = new Schedule[schedulesByDurationAndTurn.size()];
				sortedSchedules = schedulesByDurationAndTurn.toArray(sortedSchedules);
				Arrays.sort(sortedSchedules);
				allocationMatrix.get(duration).put(turn, sortedSchedules);
			}
		}
		return allocationMatrix;
	}
	
	private List<Turn> getExistentSchedulesTurns(List<Schedule> schedules) {
		List<Turn> turns = new ArrayList<Turn>();
		Iterator<Schedule> it = schedules.iterator();
		while (it.hasNext()) {
			Schedule s = it.next();
			if (!turns.contains(s.getTurn())) {
				turns.add(s.getTurn());
			}
		}
		return turns;
	}

}
